home *** CD-ROM | disk | FTP | other *** search
/ Games of Daze / Infomagic - Games of Daze (Summer 1995) (Disc 1 of 2).iso / djgpp / src / gdb-4.12 / gdb / sparclit / aload.c next >
Encoding:
C/C++ Source or Header  |  1994-02-03  |  4.5 KB  |  199 lines

  1. /* Program to load an image into the SPARClite monitor board
  2.    Copyright 1993 Free Software Foundation, Inc.
  3.  
  4. This program is free software; you can redistribute it and/or modify
  5. it under the terms of the GNU General Public License as published by
  6. the Free Software Foundation; either version 2 of the License, or
  7. (at your option) any later version.
  8.  
  9. This program is distributed in the hope that it will be useful,
  10. but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  12. GNU General Public License for more details.
  13.  
  14. You should have received a copy of the GNU General Public License
  15. along with this program; if not, write to the Free Software
  16. Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */
  17.  
  18. /* Call with:
  19.  
  20.    aload PROG TTY
  21.  
  22. ie: aload hello /dev/ttya
  23.  
  24. */
  25.  
  26. #include <stdio.h>
  27. #include <fcntl.h>
  28. #include <termios.h>
  29. #include <unistd.h>
  30. #define min(A, B) (((A) < (B)) ? (A) : (B))
  31.  
  32. #include <sys/types.h>
  33. #include <bfd.h>
  34.  
  35. extern void *malloc();
  36.  
  37. static void
  38. sys_error(msg)
  39.      char *msg;
  40. {
  41.   perror(msg);
  42.   exit(1);
  43. }
  44.  
  45. static void
  46. error(msg)
  47.      char *msg;
  48. {
  49.   fputs(msg, stdout);
  50.   fputc('\n', stdout);
  51.   exit(1);
  52. }
  53.  
  54. static FILE *ttyf;
  55.  
  56. static void
  57. sendex(outtxt, outlen, intxt, inlen, id)
  58.      unsigned char *outtxt;
  59.      int outlen;
  60.      unsigned char *intxt;
  61.      int inlen;
  62.      char *id;
  63. {
  64.   char buf[100];
  65.   int cc;
  66.  
  67.   if (outlen > 0)
  68.     {
  69.       cc = write(fileno(ttyf), outtxt, outlen);
  70.       if (cc != outlen)
  71.     sys_error("Write %s failed", id);
  72.     }
  73.  
  74.   if (inlen > 0)
  75.     {
  76.       cc = read(fileno(ttyf), buf, inlen);    /* Get reply */
  77.       if (cc != inlen)
  78.     sys_error("Read %s reply failed", id);
  79.       if (bcmp(buf, intxt, inlen) != 0)
  80.     error("Bad reply to %s", id);
  81.     }
  82. }
  83.  
  84. main(argc, argv)
  85.      int argc;
  86.      char **argv;
  87. {
  88.   struct termios termios;
  89.   unsigned char *loadaddr = (unsigned char *)0x40000000; /* Where the code goes */
  90.   int cc, progsize, i;
  91.   unsigned char buf[10];
  92.   asection *section;
  93.   bfd *pbfd;
  94.   unsigned long entry;
  95.  
  96.   pbfd = bfd_openr(argv[1], 0);
  97.  
  98.   if (!pbfd)
  99.     sys_error("Open of PROG failed");
  100.  
  101. /* setup the tty.  Must be raw, no flow control, 9600 baud */
  102.  
  103.   ttyf = fopen(argv[2], "r+");
  104.   if (!ttyf)
  105.     sys_error("Open of TTY failed");
  106.   setbuf(ttyf, NULL);        /* Strictly unbuffered */
  107.  
  108.   if (tcgetattr(fileno(ttyf), &termios))
  109.     sys_error("tcgetattr failed");
  110.  
  111.   termios.c_iflag = 0;
  112.   termios.c_oflag = 0;
  113.   termios.c_cflag = CS8 | CREAD | CLOCAL;
  114.   termios.c_lflag = 0;
  115.   termios.c_cc[VMIN] = 1;
  116.   termios.c_cc[VTIME] = 0;
  117.  
  118.   if (cfsetospeed(&termios, B9600)
  119.       || cfsetispeed(&termios, B9600))
  120.     sys_error("cfset{i|o}speed failed");
  121.  
  122.   if (tcsetattr(fileno(ttyf), TCSANOW, &termios))
  123.     sys_error("tcsetattr failed");
  124.  
  125.   sendex("", 1, "\xaa", 1, "alive?");
  126.   sendex("\x55", 1, "\x55", 1, "alive");
  127.   printf("[SPARClite appears to be alive]\n");
  128.  
  129.   if (!bfd_check_format (pbfd, bfd_object)) 
  130.     error ("It doesn't seem to be an object file");
  131.  
  132.   for (section = pbfd->sections; section; section = section->next) 
  133.     {
  134.       if (bfd_get_section_flags (pbfd, section) & SEC_ALLOC)
  135.     {
  136.       unsigned char *section_address;
  137.       unsigned long section_size;
  138.       const char *section_name;
  139.  
  140.       section_name = bfd_get_section_name (pbfd, section);
  141.  
  142.       section_address = bfd_get_section_vma (pbfd, section)
  143.         + loadaddr;
  144.       section_size = bfd_section_size (pbfd, section);
  145.  
  146.       printf("[Loading section %s at %x (%d bytes)]\n",
  147.          section_name,
  148.          section_address,
  149.          section_size);
  150.  
  151.       if (bfd_get_section_flags (pbfd, section) & SEC_LOAD) /* Text, data or lit */
  152.         {
  153.           file_ptr fptr;
  154.  
  155.           fptr = 0;
  156.  
  157.           while (section_size > 0)
  158.         {
  159.           char buffer[1024];
  160.           int count, i;
  161.           unsigned char checksum;
  162.           static char inds[] = "|/-\\";
  163.           static int k = 0;
  164.  
  165.           count = min (section_size, 1024);
  166.  
  167.           bfd_get_section_contents (pbfd, section, buffer, fptr,
  168.                         count);
  169.  
  170.           checksum = 0;
  171.           for (i=0; i < count; i++)
  172.             checksum += buffer[i];
  173.  
  174.           printf("\r%c", inds[k++ % 4]);
  175.           fflush(stdout);
  176.  
  177.           sendex("\001", 1, "\x5a", 1, "load command");
  178.           sendex(§ion_address, 4, NULL, 0, "load address");
  179.           sendex(&count, 4, NULL, 0, "program size");
  180.           sendex(buffer, count, &checksum, 1, "program");
  181.  
  182.           section_address += count;
  183.           fptr += count;
  184.           section_size -= count;
  185.         }
  186.         }
  187.       else            /* BSS */
  188.         printf ("Not loading BSS \n");
  189.     }
  190.     }
  191.  
  192.   entry = bfd_get_start_address (pbfd);
  193.   
  194.   printf("[Starting %s at 0x%x]\n", argv[1], entry);
  195.  
  196.   sendex("\003", 1, NULL, 0, "exec command");
  197.   sendex(&entry, 4, "\x55", 1, "program start");
  198. }
  199.